﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Globalization;
using Rage.Base.Abilities;
using Rage.Base.Abilities.sith_warrior;

namespace Rage.Juggernaut
{
    public partial class CalculationOptionsPanelJuggernaut : UserControl, ICalculationOptionsPanel
    {
        public CalculationOptionsPanelJuggernaut()
        {
            InitializeComponent();
        }

        #region ICalculationOptionsPanel Members
        public UserControl PanelControl { get { return this; } }

        CalculationOptionsJuggernaut calcOpts = null;
        
        private Character character;
        public Character Character
        {
            get { return character; }
            set
            {
                // Kill any old event connections
                if (character != null && character.CalculationOptions != null
                    && character.CalculationOptions is CalculationOptionsJuggernaut)
                    ((CalculationOptionsJuggernaut)character.CalculationOptions).PropertyChanged
                        -= new PropertyChangedEventHandler(CalculationOptionsPanelJuggernaut_PropertyChanged);
                // Apply the new character
                character = value;
                // Load the new CalcOpts
                LoadCalculationOptions();
                // Model Specific Code
                // Set the Data Context
                LayoutRoot.DataContext = calcOpts;
                // Add new event connections
                calcOpts.PropertyChanged += new PropertyChangedEventHandler(CalculationOptionsPanelJuggernaut_PropertyChanged);
                // Run it once for any special UI config checks
                CalculationOptionsPanelJuggernaut_PropertyChanged(null, new PropertyChangedEventArgs(""));
            }
        }

        private bool _loadingCalculationOptions;
        public void LoadCalculationOptions()
        {
            _loadingCalculationOptions = true;
            if (Character.CalculationOptions == null) Character.CalculationOptions = new CalculationOptionsJuggernaut();
            calcOpts = Character.CalculationOptions as CalculationOptionsJuggernaut;

            // Model Specific Code
            bool showSliders = false;
            if (calcOpts.RankingMode == 1)
                showSliders = true;

            RefreshRotationPanel();
            RefreshRotationPanelOpeners();
            RefreshRotationPanelExecutes();

            LB_HitsToSurvive.Visibility  = (showSliders ? Visibility.Visible : Visibility.Collapsed);
            NUD_HitsToSurvive.Visibility = (showSliders ? Visibility.Visible : Visibility.Collapsed);
            LB_ThreatScale.Visibility    = (showSliders ? Visibility.Visible : Visibility.Collapsed);
            NUD_ThreatScale.Visibility   = (showSliders ? Visibility.Visible : Visibility.Collapsed);

            _loadingCalculationOptions = false;
        }

        void CalculationOptionsPanelJuggernaut_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (_loadingCalculationOptions) { return; }

            // This would handle any special changes, especially combobox assignments, but not when the pane is trying to load
            switch (e.PropertyName)
            {
                case "RankingMode":
                    bool showSliders = false;
                    if (calcOpts.RankingMode == 1)
                        showSliders = true;

                    LB_HitsToSurvive.Visibility = (showSliders ? Visibility.Visible : Visibility.Collapsed);
                    NUD_HitsToSurvive.Visibility = (showSliders ? Visibility.Visible : Visibility.Collapsed);
                    LB_ThreatScale.Visibility = (showSliders ? Visibility.Visible : Visibility.Collapsed);
                    NUD_ThreatScale.Visibility = (showSliders ? Visibility.Visible : Visibility.Collapsed);
                    break;
            }
            this.UpdateLayout();
            if (Character != null) { Character.OnCalculationsInvalidated(); }
        }
        #endregion

        private void btnResetHitsToSurvive_Click(object sender, RoutedEventArgs e) { calcOpts.HitsToSurvive = 3.1f; }
        private void btnResetBurstScale_Click(object sender, RoutedEventArgs e) { calcOpts.BurstScale = 3.0f; }
        private void btnResetThreatScale_Click(object sender, RoutedEventArgs e) { calcOpts.ThreatScale = 5f; }
        private void btnResetDPSScale_Click(object sender, RoutedEventArgs e) { calcOpts.DPSScale = 1f; }

        #region Rotations
        public static List<Type> RelevantClassAbilityTpes = new List<Type>()
        {
            typeof(Assault),
            typeof(SunderingAssault),
            typeof(CrushingBlow),
            typeof(ViciousSlash),
            typeof(Retaliation),
            typeof(Ravage),
            typeof(ForceScream),
            typeof(ViciousThrow),
            typeof(Smash),
            typeof(SweepingSlash),
            typeof(Backhand),
            typeof(ForceChoke),
            typeof(SaberThrow),
            typeof(ForceCharge),
            typeof(ForcePush),
            typeof(ThreateningScream),
            typeof(Taunt),
            typeof(Invincible),
            typeof(EndurePain2),
            typeof(SaberWard),
            typeof(Unleash),
            typeof(Intercede),
            typeof(Enrage),
            typeof(Disruption),
            typeof(SavageKick),
            typeof(ChillingScream),
            typeof(PommelStrike),
            typeof(IntimidatingRoar),
        };
        #region Standard
        private void CK_ExecRotEnabler_CheckedChanged(object sender, RoutedEventArgs e) { if (Character != null) { Character.OnCalculationsInvalidated(); } }
        private void RefreshRotationPanel()
        {
            m_loadingCalculationOptions = true;
            AbilityRotation rotation = calcOpts.GetActiveRotation();
            CB_Rotation.Items.Clear();
            foreach (AbilityRotation r in calcOpts.Rotations) {
                CB_Rotation.Items.Add(r.Name);
            }
            CB_Rotation.SelectedItem = rotation.Name;
            Menu_Rotation.Items.Clear();
            foreach (Type classability in HelperFunction.ALL_CLASSABILITIES_TYPES.Where(i => RelevantClassAbilityTpes.Contains(i)).OrderBy(o => o.Name)) {
                if (GetActivePriorities() == null) { break; }
                if (!GetActivePriorities().Contains(classability)
                    && !CB_Filler.Items.Contains(classability.Name)) {
                    Menu_Rotation.Items.Add(classability.Name);
                }
            }
            List_Rotation.Items.Clear();
            if (GetActivePriorities() != null) {
                foreach (Type classability in GetActivePriorities()) {
                    List_Rotation.Items.Add(classability.Name);
                }
            }
            CB_Filler.SelectedItem = rotation.Filler;
            RefreshRotationButtons();
            m_loadingCalculationOptions = false;
        }
        private void RefreshRotationPanelOpeners()
        {
            m_loadingCalculationOptions = true;
            AbilityRotation rotationOpener = calcOpts.GetActiveRotationOpener();
            CB_RotationOpeners.Items.Clear();
            foreach (AbilityRotation r in calcOpts.RotationsOpeners) {
                CB_RotationOpeners.Items.Add(r.Name);
            }
            CB_RotationOpeners.SelectedItem = rotationOpener.Name;
            Menu_RotationOpeners.Items.Clear();
            foreach (Type classability in HelperFunction.ALL_CLASSABILITIES_TYPES.Where(i => RelevantClassAbilityTpes.Contains(i)).OrderBy(o => o.Name)) {
                if (GetActivePrioritiesOpener() == null) { break; }
                if (!GetActivePrioritiesOpener().Contains(classability)) {
                    Menu_RotationOpeners.Items.Add(classability.Name);
                }
            }
            List_RotationOpeners.Items.Clear();
            if (GetActivePrioritiesOpener() != null) {
                foreach (Type classability in GetActivePrioritiesOpener()) {
                    List_RotationOpeners.Items.Add(classability.Name);
                }
            }
            RefreshRotationButtonsOpeners();
            m_loadingCalculationOptions = false;
        }
        private void RefreshRotationPanelExecutes()
        {
            m_loadingCalculationOptions = true;
            AbilityRotation rotationExecutes = calcOpts.GetActiveRotationExecute();
            CB_RotationExecutes.Items.Clear();
            foreach (AbilityRotation r in calcOpts.RotationsExecutes) {
                CB_RotationExecutes.Items.Add(r.Name);
            }
            CB_RotationExecutes.SelectedItem = rotationExecutes.Name;
            Menu_RotationExecutes.Items.Clear();
            foreach (Type classability in HelperFunction.ALL_CLASSABILITIES_TYPES.Where(i => RelevantClassAbilityTpes.Contains(i)).OrderBy(o => o.Name)) {
                if (GetActivePrioritiesExecutes() == null) { break; }
                if (!GetActivePrioritiesExecutes().Contains(classability)
                    && !CB_FillerExecutes.Items.Contains(classability.Name)) {
                    Menu_RotationExecutes.Items.Add(classability.Name);
                }
            }
            List_RotationExecutes.Items.Clear();
            if (GetActivePrioritiesExecutes() != null) {
                foreach (Type classability in GetActivePrioritiesExecutes()) {
                    if (classability == null) { continue; }
                    List_RotationExecutes.Items.Add(classability.Name);
                }
            }
            CB_FillerExecutes.SelectedItem = rotationExecutes.Filler;
            RefreshRotationButtonsExecutes();
            m_loadingCalculationOptions = false;
        }
        private void RefreshRotationButtons()
        {
            int itemCount = List_Rotation.Items.Count;
            int curIndex = List_Rotation.SelectedIndex;

            BT_RotationAdd.IsEnabled = Menu_Rotation.SelectedIndex >= 0;
            BT_RotationUp.IsEnabled = curIndex > 0;
            BT_RotationDown.IsEnabled = curIndex >= 0 && curIndex < itemCount - 1;
            BT_RotationClear.IsEnabled = itemCount > 0;

            //LB_RotationError.Text = calcOpts.GetActiveRotation().GetError();
        }
        private void RefreshRotationButtonsOpeners()
        {
            int itemCount = List_RotationOpeners.Items.Count;
            int curIndex = List_RotationOpeners.SelectedIndex;

            BT_RotationAddOpeners.IsEnabled = Menu_RotationOpeners.SelectedIndex >= 0;
            BT_RotationUpOpeners.IsEnabled = curIndex > 0;
            BT_RotationDownOpeners.IsEnabled = curIndex >= 0 && curIndex < itemCount - 1;
            BT_RotationClearOpeners.IsEnabled = itemCount > 0;

            //LB_RotationError.Text = calcOpts.GetActiveRotation().GetError();
        }
        private void RefreshRotationButtonsExecutes()
        {
            int itemCount = List_RotationExecutes.Items.Count;
            int curIndex = List_RotationExecutes.SelectedIndex;

            BT_RotationAddExecutes.IsEnabled = Menu_RotationExecutes.SelectedIndex >= 0;
            BT_RotationUpExecutes.IsEnabled = curIndex > 0;
            BT_RotationDownExecutes.IsEnabled = curIndex >= 0 && curIndex < itemCount - 1;
            BT_RotationClearExecutes.IsEnabled = itemCount > 0;

            //LB_RotationErrorExecutes.Text = calcOpts.GetActiveRotation().GetError();
        }
        private void RotationSwap(int swapWith)
        {
            int oldIndex = List_Rotation.SelectedIndex;
            int newIndex = oldIndex + swapWith;
            Utilities.SwapElements(GetActivePriorities(), oldIndex, newIndex);
            RefreshRotationPanel();
            List_Rotation.SelectedIndex = newIndex;
        }
        private void RotationSwapOpeners(int swapWith)
        {
            int oldIndex = List_RotationOpeners.SelectedIndex;
            int newIndex = oldIndex + swapWith;
            Utilities.SwapElements(GetActivePrioritiesOpener(), oldIndex, newIndex);
            RefreshRotationPanelOpeners();
            List_RotationOpeners.SelectedIndex = newIndex;
        }
        private void RotationSwapExecutes(int swapWith)
        {
            int oldIndex = List_RotationExecutes.SelectedIndex;
            int newIndex = oldIndex + swapWith;
            Utilities.SwapElements(GetActivePrioritiesExecutes(), oldIndex, newIndex);
            RefreshRotationPanelExecutes();
            List_RotationExecutes.SelectedIndex = newIndex;
        }
        private List<Type> GetActivePriorities() { if (calcOpts.ActiveRotation == null) { return null; } return calcOpts.ActiveRotation.ClassAbilityPriority; }
        private List<Type> GetActivePrioritiesOpener() { if (calcOpts.ActiveRotationOpener == null) { return null; } return calcOpts.ActiveRotationOpener.ClassAbilityPriority; }
        private List<Type> GetActivePrioritiesExecutes() { if (calcOpts.ActiveRotationExecute == null) { return null; } return calcOpts.ActiveRotationExecute.ClassAbilityPriority; }
        private void AddToActivePriorities(Type t) { calcOpts.ActiveRotation.ClassAbilityPriority.Add(t); }
        private void AddToActivePrioritiesOpener(Type t) { calcOpts.ActiveRotationOpener.ClassAbilityPriority.Add(t); }
        private void AddToActivePrioritiesExecutes(Type t) { calcOpts.ActiveRotationExecute.ClassAbilityPriority.Add(t); }
        private void BT_RotationAdd_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            m_loadingCalculationOptions = true;
            Type t = Type.GetType("Rage.Base.Abilities.sith_warrior." + (Menu_Rotation.SelectedItem as string) + ",Rage.Base.WPF", true, true);
            GetActivePriorities().Add(t);
            RefreshRotationPanel();
            Character.OnCalculationsInvalidated();
            m_loadingCalculationOptions = false;
        }
        private void BT_RotationAddOpeners_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            m_loadingCalculationOptions = true;
            Type t = Type.GetType("Rage.Base.Abilities.sith_warrior." + (Menu_RotationOpeners.SelectedItem as string) + ",Rage.Base.WPF", true, true);
            AddToActivePrioritiesOpener(t);
            RefreshRotationPanelOpeners();
            Character.OnCalculationsInvalidated();
            m_loadingCalculationOptions = false;
        }
        private void BT_RotationAddExecutes_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            m_loadingCalculationOptions = true;
            Type t = Type.GetType("Rage.Base.Abilities.sith_warrior." + (Menu_RotationExecutes.SelectedItem as string) + ",Rage.Base.WPF", true, true);
            GetActivePrioritiesExecutes().Add(t);
            RefreshRotationPanelExecutes();
            Character.OnCalculationsInvalidated();
            m_loadingCalculationOptions = false;
        }
        private void BT_RotationRemove_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            int index = List_Rotation.SelectedIndex;
            if (index < 0) { return; }
            GetActivePriorities().RemoveAt(index);
            RefreshRotationPanel();
            int itemCount = List_Rotation.Items.Count;
            if (itemCount > 0)
            {
                List_Rotation.SelectedIndex = Math.Min(index, itemCount - 1);
            }
            Character.OnCalculationsInvalidated();
        }
        private void BT_RotationRemoveOpeners_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            int index = List_RotationOpeners.SelectedIndex;
            if (index < 0) { return; }
            if (GetActivePrioritiesOpener() == null) { return; }
            GetActivePrioritiesOpener().RemoveAt(index);
            RefreshRotationPanelOpeners();
            int itemCount = List_RotationOpeners.Items.Count;
            if (itemCount > 0)
            {
                List_RotationOpeners.SelectedIndex = Math.Min(index, itemCount - 1);
            }
            Character.OnCalculationsInvalidated();
        }
        private void BT_RotationRemoveExecutes_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            int index = List_RotationExecutes.SelectedIndex;
            if (index < 0) { return; }
            GetActivePrioritiesExecutes().RemoveAt(index);
            RefreshRotationPanelExecutes();
            int itemCount = List_RotationExecutes.Items.Count;
            if (itemCount > 0)
            {
                List_RotationExecutes.SelectedIndex = Math.Min(index, itemCount - 1);
            }
            Character.OnCalculationsInvalidated();
        }
        private void BT_RotationUp_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            RotationSwap(-1);
            Character.OnCalculationsInvalidated();
        }
        private void BT_RotationUpOpeners_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            RotationSwapOpeners(-1);
            Character.OnCalculationsInvalidated();
        }
        private void BT_RotationUpExecutes_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            RotationSwapExecutes(-1);
            Character.OnCalculationsInvalidated();
        }
        private void BT_RotationDown_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            RotationSwap(1);
            Character.OnCalculationsInvalidated();
        }
        private void BT_RotationDownOpeners_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            RotationSwapOpeners(1);
            Character.OnCalculationsInvalidated();
        }
        private void BT_RotationDownExecutes_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            RotationSwapExecutes(1);
            Character.OnCalculationsInvalidated();
        }
        private void BT_RotationClear_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            GetActivePriorities().Clear();
            RefreshRotationPanel();
            Character.OnCalculationsInvalidated();
        }
        private void BT_RotationClearOpeners_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            GetActivePrioritiesOpener().Clear();
            RefreshRotationPanelOpeners();
            Character.OnCalculationsInvalidated();
        }
        private void BT_RotationClearExecutes_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            GetActivePriorities().Clear();
            RefreshRotationPanelExecutes();
            Character.OnCalculationsInvalidated();
        }
        private void Menu_Rotation_SelectedIndexChanged(object sender, SelectionChangedEventArgs e) { if (m_loadingCalculationOptions) { return; } RefreshRotationButtons(); }
        private void Menu_RotationOpeners_SelectedIndexChanged(object sender, SelectionChangedEventArgs e) { if (m_loadingCalculationOptions) { return; } RefreshRotationButtonsOpeners(); }
        private void Menu_RotationExecutes_SelectedIndexChanged(object sender, SelectionChangedEventArgs e) { if (m_loadingCalculationOptions) { return; } RefreshRotationButtonsExecutes(); }
        private void List_Rotation_SelectedIndexChanged(object sender, SelectionChangedEventArgs e) { if (m_loadingCalculationOptions) { return; } RefreshRotationButtons(); }
        private void List_RotationOpeners_SelectedIndexChanged(object sender, SelectionChangedEventArgs e) { if (m_loadingCalculationOptions) { return; } RefreshRotationButtonsOpeners(); }
        private void List_RotationExecutes_SelectedIndexChanged(object sender, SelectionChangedEventArgs e) { if (m_loadingCalculationOptions) { return; } RefreshRotationButtonsExecutes(); }
        private void CB_Filler_SelectedIndexChanged(object sender, SelectionChangedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            calcOpts.GetActiveRotation().Filler = (string)CB_Filler.SelectedItem;
            Character.OnCalculationsInvalidated();
        }
        private void CB_FillerExecutes_SelectedIndexChanged(object sender, SelectionChangedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            calcOpts.GetActiveRotationExecute().Filler = (string)CB_FillerExecutes.SelectedItem;
            Character.OnCalculationsInvalidated();
        }
        private void CB_Rotation_SelectedIndexChanged(object sender, SelectionChangedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }
            calcOpts.ActiveRotationIndex = CB_Rotation.SelectedIndex;
            RefreshRotationPanel();
            Character.OnCalculationsInvalidated();
        }
        private void CB_RotationOpeners_SelectedIndexChanged(object sender, SelectionChangedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }
            calcOpts.ActiveRotationIndexOpeners = CB_RotationOpeners.SelectedIndex;
            RefreshRotationPanelOpeners();
            Character.OnCalculationsInvalidated();
        }
        private void CB_RotationExecutes_SelectedIndexChanged(object sender, SelectionChangedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }
            calcOpts.ActiveRotationIndexExecutes = CB_RotationExecutes.SelectedIndex;
            RefreshRotationPanelExecutes();
            Character.OnCalculationsInvalidated();
        }
        private void BT_NewRotation_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            Base.TextInputDialog d = new Base.TextInputDialog("New Rotation", "Choose a name:", "", calcOpts.Rotations.Select(x => x.Name).ToList());
            d.Closed += new EventHandler((a, b) => {
                if (d.DialogResult.GetValueOrDefault()) {
                    calcOpts.Rotations.Add(new AbilityRotation(d.Result, "Assault", null));
                    calcOpts.ActiveRotationIndex = calcOpts.Rotations.Count - 1;
                    RefreshRotationPanel();
                    Character.OnCalculationsInvalidated();
                }
            });
            d.Show();
        }
        private void BT_NewRotationOpeners_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            Base.TextInputDialog d = new Base.TextInputDialog("New Opener Rotation", "Choose a name:", "", calcOpts.RotationsOpeners.Select(x => x.Name));
            d.Closed += new EventHandler((a, b) =>
            {
                if (d.DialogResult.GetValueOrDefault())
                {
                    calcOpts.RotationsOpeners.Add(new AbilityRotation(d.Result, "Assault", null));
                    calcOpts.ActiveRotationIndexOpeners = calcOpts.RotationsOpeners.Count - 1;
                    RefreshRotationPanelOpeners();
                    Character.OnCalculationsInvalidated();
                }
            });
            d.Show();
        }
        private void BT_NewRotationExecutes_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            Base.TextInputDialog d = new Base.TextInputDialog("New Executes Rotation", "Choose a name:", "", calcOpts.RotationsExecutes.Select(x => x.Name));
            d.Closed += new EventHandler((a, b) =>
            {
                if (d.DialogResult.GetValueOrDefault())
                {
                    calcOpts.RotationsExecutes.Add(new AbilityRotation(d.Result, "Assault", null));
                    calcOpts.ActiveRotationIndexExecutes = calcOpts.RotationsExecutes.Count - 1;
                    RefreshRotationPanelExecutes();
                    Character.OnCalculationsInvalidated();
                }
            });
            d.Show();
        }
        private void BT_RotationRename_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            AbilityRotation rotation = calcOpts.GetActiveRotation();
            Base.TextInputDialog d = new Base.TextInputDialog("Rename Rotation", "Rename to:", rotation.Name,
                calcOpts.Rotations.Select(x => x.Name).Where(x => x != rotation.Name));
            d.Closed += new EventHandler((a, b) =>
            {
                if (d.DialogResult.GetValueOrDefault())
                {
                    rotation.Name = d.Result;
                    RefreshRotationPanel();
                    Character.OnCalculationsInvalidated();
                }
            });
            d.Show();
        }
        private void BT_RotationRenameOpeners_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            AbilityRotation rotationOpeners = calcOpts.GetActiveRotationOpener();
            Base.TextInputDialog d = new Base.TextInputDialog("Rename Opener Rotation", "Rename to:", rotationOpeners.Name,
                calcOpts.RotationsOpeners.Select(x => x.Name).Where(x => x != rotationOpeners.Name));
            d.Closed += new EventHandler((a, b) =>
            {
                if (d.DialogResult.GetValueOrDefault())
                {
                    rotationOpeners.Name = d.Result;
                    RefreshRotationPanelOpeners();
                    Character.OnCalculationsInvalidated();
                }
            });
            d.Show();
        }
        private void BT_RotationRenameExecutes_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            AbilityRotation rotationExecutes = calcOpts.GetActiveRotationExecute();
            Base.TextInputDialog d = new Base.TextInputDialog("Rename Executes Rotation", "Rename to:", rotationExecutes.Name,
                calcOpts.RotationsExecutes.Select(x => x.Name).Where(x => x != rotationExecutes.Name));
            d.Closed += new EventHandler((a, b) =>
            {
                if (d.DialogResult.GetValueOrDefault())
                {
                    rotationExecutes.Name = d.Result;
                    RefreshRotationPanelExecutes();
                    Character.OnCalculationsInvalidated();
                }
            });
            d.Show();
        }
        private void BT_DeleteRotationOpeners_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            calcOpts.RemoveActiveRotationOpeners();
            if (calcOpts.RotationsOpeners.Count == 0)
            {
                calcOpts.RotationsOpeners.Add(new AbilityRotation("New Opener Rotation", "Shadow Bolt", null));
                calcOpts.ActiveRotationIndexOpeners = 0;
            }

            RefreshRotationPanelOpeners();
            Character.OnCalculationsInvalidated();
        }
        private void BT_DeleteRotation_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            calcOpts.RemoveActiveRotation();
            if (calcOpts.Rotations.Count == 0)
            {
                calcOpts.Rotations.Add(new AbilityRotation("New Rotation", "Assault", null));
                calcOpts.ActiveRotationIndex = 0;
            }

            RefreshRotationPanel();
            Character.OnCalculationsInvalidated();
        }
        private void BT_DeleteRotationExecutes_Click(object sender, RoutedEventArgs e)
        {
            if (m_loadingCalculationOptions) { return; }

            calcOpts.RemoveActiveRotationExecutes();
            if (calcOpts.RotationsExecutes.Count == 0)
            {
                calcOpts.RotationsExecutes.Add(new AbilityRotation("New Executes Rotation", "Assault", null));
                calcOpts.ActiveRotationIndexExecutes = 0;
            }

            RefreshRotationPanelExecutes();
            Character.OnCalculationsInvalidated();
        }
        #endregion

        private bool m_loadingCalculationOptions;
        //private Character m_character;
        #endregion
    }

    #region Converters
    public class RankingModeConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            int rankingMode = (int)value;
            switch (rankingMode)
            {
                case 2: 
                    return "Burst Time";
                case 3:
                    return "CT Coverage";
                default: return "Mitigation Scale";
            }
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string rankingMode = (string)value;
            switch (rankingMode)
            {
                case "Burst Time": 
                    return 2;
                case "CT Coverage":
                    return 3;
                default: return 1;
            }
        }
    }
    public class ThreatValueConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            float threatValue = (float)value;
            if (threatValue == 1f) return "Almost None";
            if (threatValue == 5f) return "MT";
            if (threatValue == 25f) return "OT";
            if (threatValue == 50f) return "Crazy About Threat";
            else return "Custom...";
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string threatValue = (string)value;
            switch (threatValue)
            {
                case "Almost None": return 1f;
                case "MT": return 5f;
                case "OT": return 25f;
                case "Crazy About Threat": return 50f;
            }
            return null;
        }
    }
    public class PercentConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (targetType == typeof(float)) return System.Convert.ToSingle(value) * 100.0f;
            if (targetType == typeof(double)) return System.Convert.ToDouble(value) * 100.0d;
            return System.Convert.ToDouble(value) * 100.0d;
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (targetType == typeof(float)) return System.Convert.ToSingle(value) / 100f;
            if (targetType == typeof(double)) return System.Convert.ToDouble(value) / 100d;
            return System.Convert.ToDouble(value) / 100d;
        }
    }
    #endregion
}
